<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Node Placement</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Node Placement' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../intern.html">Inter Modules</a></li><li><a href="index.html">bytecode</a></li><li><a href="index.html#2">Chapter 2: The Trees</a></li><li><b>Node Placement</b></li></ul></div>
<p class="purpose">Moving nodes in a tree, adding them to a tree, removing them from a tree.</p>

<ul class="toc"><li><a href="2-np.html#SP4">&#167;4. Level correction</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. </b>Each node contains pointers to its previous and next child of the same parent;
to its parent node; and to its first child node. There are many implied
invariants in that arrangement (e.g., that if X has a child then the parent of
that child is X), and it would be eaxy to get all this wrong.
</p>

<p class="commentary">All modifications of the links between nodes must therefore be made by one of
only three functions:
</p>

<ul class="items"><li>&#9679; <span class="extract"><span class="extract-syntax">NodePlacement::remove(C)</span></span> removes the node <span class="extract"><span class="extract-syntax">C</span></span> from the tree.
</li><li>&#9679; <span class="extract"><span class="extract-syntax">NodePlacement::move_to(C, IBM)</span></span> moves the node <span class="extract"><span class="extract-syntax">C</span></span> to the position
bookmarked by <span class="extract"><span class="extract-syntax">IBM</span></span>. <span class="extract"><span class="extract-syntax">C</span></span> can but need not already be in the tree.
</li><li>&#9679; <span class="extract"><span class="extract-syntax">NodePlacement::move_to_moving_bookmark(C, IBM)</span></span> moves the node <span class="extract"><span class="extract-syntax">F</span></span> to
the position bookmarked by <span class="extract"><span class="extract-syntax">IBM</span></span>, but also adjusts <span class="extract"><span class="extract-syntax">IBM</span></span> to be the natural
next write position.
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodePlacement::remove</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">NodePlacement::remove</span></span>:<br/>Symbols - <a href="2-sym.html#SP16">&#167;16</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-np.html#SP1_1" class="named-paragraph-link"><span class="named-paragraph">Extricate C from its current tree position</span><span class="named-paragraph-number">1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodePlacement::move_to</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">NodePlacement::move_to</span></span>:<br/><a href="2-np.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">inter_bookmark</span><span class="plain-syntax"> </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="2-np.html#SP1_1" class="named-paragraph-link"><span class="named-paragraph">Extricate C from its current tree position</span><span class="named-paragraph-number">1.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">placement_wrt_R</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">AS_FIRST_CHILD_OF_NODEPLACEMENT:</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="2-np.html#SP1_2" class="named-paragraph-link"><span class="named-paragraph">Make C the first child of R</span><span class="named-paragraph-number">1.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">AS_LAST_CHILD_OF_NODEPLACEMENT:</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="2-np.html#SP1_3" class="named-paragraph-link"><span class="named-paragraph">Make C the last child of R</span><span class="named-paragraph-number">1.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">AFTER_NODEPLACEMENT:</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">IMMEDIATELY_AFTER_NODEPLACEMENT:</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="2-np.html#SP1_4" class="named-paragraph-link"><span class="named-paragraph">Insert C after R</span><span class="named-paragraph-number">1.4</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">BEFORE_NODEPLACEMENT:</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="2-np.html#SP1_5" class="named-paragraph-link"><span class="named-paragraph">Insert C before R</span><span class="named-paragraph-number">1.5</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">default:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"unimplemented"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP1_1" class="paragraph-anchor"></a><b>&#167;1.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Extricate C from its current tree position</span><span class="named-paragraph-number">1.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OP</span><span class="plain-syntax"> = </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::parent</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">OP</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::first_child</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OP</span><span class="plain-syntax">) == </span><span class="identifier-syntax">C</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_first_child_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OP</span><span class="plain-syntax">, </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::next</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">));</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::last_child</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OP</span><span class="plain-syntax">) == </span><span class="identifier-syntax">C</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_last_child_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OP</span><span class="plain-syntax">, </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::previous</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">));</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OB</span><span class="plain-syntax"> = </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::previous</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OD</span><span class="plain-syntax"> = </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::next</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">OB</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_next_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OB</span><span class="plain-syntax">, </span><span class="identifier-syntax">OD</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">OD</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">OD</span><span class="plain-syntax">, </span><span class="identifier-syntax">OB</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_parent_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_next_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-np.html#SP1">&#167;1</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP1_2" class="paragraph-anchor"></a><b>&#167;1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make C the first child of R</span><span class="named-paragraph-number">1.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_parent_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::first_child</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_last_child_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_next_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_next_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_first_child_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-np.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_3" class="paragraph-anchor"></a><b>&#167;1.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Make C the last child of R</span><span class="named-paragraph-number">1.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_parent_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::last_child</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">B</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_first_child_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_next_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">B</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">B</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_last_child_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-np.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_4" class="paragraph-anchor"></a><b>&#167;1.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Insert C after R</span><span class="named-paragraph-number">1.4</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::parent</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't move C before R when R is nowhere"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_parent_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::last_child</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">) == </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_last_child_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">D</span><span class="plain-syntax"> = </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::next</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">D</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"inter tree broken"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_next_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">D</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">D</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_next_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-np.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP1_5" class="paragraph-anchor"></a><b>&#167;1.5. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Insert C before R</span><span class="named-paragraph-number">1.5</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax"> = </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::parent</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"can't move C before R when R is nowhere"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_parent_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::first_child</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">) == </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_first_child_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax"> = </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::previous</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">B</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"inter tree broken"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">B</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_next_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">B</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_next_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP2" class="function-link"><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-np.html#SP1">&#167;1</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>The names of these functions are intended to discourage their use. They
should only be used by <a href="2-np.html#SP1" class="internal">NodePlacement::move_to</a>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">NodePlacement::set_previous_UNSAFE</span></span>:<br/><a href="2-np.html#SP1_1">&#167;1.1</a>, <a href="2-np.html#SP1_2">&#167;1.2</a>, <a href="2-np.html#SP1_3">&#167;1.3</a>, <a href="2-np.html#SP1_4">&#167;1.4</a>, <a href="2-np.html#SP1_5">&#167;1.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax">) </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">previous_itn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">V</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodePlacement::set_next_UNSAFE</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">NodePlacement::set_next_UNSAFE</span></span>:<br/><a href="2-np.html#SP1_1">&#167;1.1</a>, <a href="2-np.html#SP1_2">&#167;1.2</a>, <a href="2-np.html#SP1_3">&#167;1.3</a>, <a href="2-np.html#SP1_4">&#167;1.4</a>, <a href="2-np.html#SP1_5">&#167;1.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax">) </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_itn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">V</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodePlacement::set_first_child_UNSAFE</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">NodePlacement::set_first_child_UNSAFE</span></span>:<br/><a href="2-np.html#SP1_1">&#167;1.1</a>, <a href="2-np.html#SP1_2">&#167;1.2</a>, <a href="2-np.html#SP1_3">&#167;1.3</a>, <a href="2-np.html#SP1_5">&#167;1.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax">) </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_child_itn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">V</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodePlacement::set_last_child_UNSAFE</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">NodePlacement::set_last_child_UNSAFE</span></span>:<br/><a href="2-np.html#SP1_1">&#167;1.1</a>, <a href="2-np.html#SP1_2">&#167;1.2</a>, <a href="2-np.html#SP1_3">&#167;1.3</a>, <a href="2-np.html#SP1_4">&#167;1.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax">) </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">last_child_itn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">V</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodePlacement::set_parent_UNSAFE</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">NodePlacement::set_parent_UNSAFE</span></span>:<br/><a href="2-np.html#SP1_1">&#167;1.1</a>, <a href="2-np.html#SP1_2">&#167;1.2</a>, <a href="2-np.html#SP1_3">&#167;1.3</a>, <a href="2-np.html#SP1_4">&#167;1.4</a>, <a href="2-np.html#SP1_5">&#167;1.5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">V</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax">) </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">parent_itn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">V</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. </b>This is more intricate than <a href="2-np.html#SP1" class="internal">NodePlacement::move_to</a>. The differences are
basically that:
</p>

<ul class="items"><li>&#9679; <span class="extract"><span class="extract-syntax">IBM</span></span> is considered to be a write position which should move along with
each forwards write that is made, as if it's a sort of cursor. By "forwards
write", we mean anything other than <span class="extract"><span class="extract-syntax">BEFORE_NODEPLACEMENT</span></span>; the cursor does
not move backwards. So if we call this function to write A, B, C, ... after R,
the result is ... R, A, B, C..., the cursor advancing one position each time;
and if we call it to write A, B, C, ... before R, the result is ... A, B, C, R,
..., with the cursor staying put at R.
</li><li>&#9679; In the two "after" placements, we look at the level assigned to the new
node <span class="extract"><span class="extract-syntax">C</span></span>, which tells us what hierarchical depth it should be at in the tree;
if this is a different level from the bookmark's level, the bookmark is moved
to that new level.
</li></ul>
<p class="commentary">For example, suppose we have this fragment of tree:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Level</span><span class="plain-syntax">   </span><span class="constant-syntax">6</span><span class="plain-syntax">...7...8...</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Nodes</span><span class="plain-syntax">   </span><span class="identifier-syntax">node1</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node2</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node3</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">node4</span><span class="plain-syntax">   &lt;--- </span><span class="identifier-syntax">Bookmark</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="constant-syntax">AFTER_NODEPLACEMENT</span><span class="plain-syntax"> </span><span class="identifier-syntax">wrt</span><span class="plain-syntax"> </span><span class="identifier-syntax">node4</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node5</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">node6</span>
</pre>
<p class="commentary">If <span class="extract"><span class="extract-syntax">C</span></span> is to be at level 8, the same level as the bookmark, we get:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Level</span><span class="plain-syntax">   </span><span class="constant-syntax">6</span><span class="plain-syntax">...7...8...</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Nodes</span><span class="plain-syntax">   </span><span class="identifier-syntax">node1</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node2</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node3</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">node4</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">C</span><span class="plain-syntax">       &lt;--- </span><span class="identifier-syntax">Bookmark</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="constant-syntax">AFTER_NODEPLACEMENT</span><span class="plain-syntax"> </span><span class="identifier-syntax">wrt</span><span class="plain-syntax"> </span><span class="identifier-syntax">C</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node5</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">node6</span>
</pre>
<p class="commentary">If instead it is to be at level 6:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Level</span><span class="plain-syntax">   </span><span class="constant-syntax">6</span><span class="plain-syntax">...7...8...</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Nodes</span><span class="plain-syntax">   </span><span class="identifier-syntax">node1</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node2</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node3</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">node4</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node5</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">node6</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">C</span><span class="plain-syntax">               &lt;--- </span><span class="identifier-syntax">Bookmark</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="constant-syntax">AFTER_NODEPLACEMENT</span><span class="plain-syntax"> </span><span class="identifier-syntax">wrt</span><span class="plain-syntax"> </span><span class="identifier-syntax">C</span>
</pre>
<p class="commentary">Here, C has "bubbled up" the tree. Finally, if it is to be at level 9:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">Level</span><span class="plain-syntax">   </span><span class="constant-syntax">6</span><span class="plain-syntax">...7...8...</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">Nodes</span><span class="plain-syntax">   </span><span class="identifier-syntax">node1</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node2</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node3</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">node4</span>
<span class="plain-syntax">                        </span><span class="identifier-syntax">C</span><span class="plain-syntax">   &lt;--- </span><span class="identifier-syntax">Bookmark</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="constant-syntax">AFTER_NODEPLACEMENT</span><span class="plain-syntax"> </span><span class="identifier-syntax">wrt</span><span class="plain-syntax"> </span><span class="identifier-syntax">C</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">node5</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">node6</span>
</pre>
<p class="commentary">Note that if C is to be at level 10, an internal error is thrown; there is no
way to reach as low as that from <span class="extract"><span class="extract-syntax">node4</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodePlacement::move_to_moving_bookmark</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">NodePlacement::move_to_moving_bookmark</span></span>:<br/>Transmigration - <a href="2-trn.html#SP3_3">&#167;3.3</a>, <a href="2-trn.html#SP5_1_1">&#167;5.1.1</a>, <a href="2-trn.html#SP5_2_1_1">&#167;5.2.1.1</a><br/>Inter in Binary Files - <a href="3-iibf.html#SP10_1_5">&#167;10.1.5</a><br/>The Comment Construct - <a href="4-tcc.html#SP2">&#167;2</a><br/>The Constant Construct - <a href="4-tcc2.html#SP2">&#167;2</a>, <a href="4-tcc2.html#SP4">&#167;4</a><br/>The Insert Construct - <a href="4-tic.html#SP2">&#167;2</a><br/>The Instance Construct - <a href="4-tic2.html#SP2">&#167;2</a><br/>The Nop Construct - <a href="4-tnc.html#SP2">&#167;2</a><br/>The Origin Construct - <a href="4-toc.html#SP2">&#167;2</a><br/>The Package Construct - <a href="4-tpc.html#SP4">&#167;4</a><br/>The PackageType Construct - <a href="4-tpc2.html#SP2">&#167;2</a><br/>The Permission Construct - <a href="4-tpc3.html#SP2">&#167;2</a><br/>The Pragma Construct - <a href="4-tpc4.html#SP2">&#167;2</a><br/>The Primitive Construct - <a href="4-tpc5.html#SP2">&#167;2</a><br/>The Property Construct - <a href="4-tpc6.html#SP2">&#167;2</a><br/>The PropertyValue Construct - <a href="4-tpc7.html#SP2">&#167;2</a><br/>The Provenance Construct - <a href="4-tpc8.html#SP2">&#167;2</a><br/>The Typename Construct - <a href="4-ttc.html#SP2">&#167;2</a><br/>The Variable Construct - <a href="4-tvc.html#SP2">&#167;2</a><br/>The Assembly Construct - <a href="5-tac.html#SP2">&#167;2</a><br/>The Cast Construct - <a href="5-tcc.html#SP2">&#167;2</a><br/>The Code Construct - <a href="5-tcc2.html#SP2">&#167;2</a><br/>The Evaluation Construct - <a href="5-tec.html#SP2">&#167;2</a><br/>The Inv Construct - <a href="5-tic.html#SP3">&#167;3</a><br/>The Lab Construct - <a href="5-tlc.html#SP2">&#167;2</a><br/>The Label Construct - <a href="5-tlc2.html#SP2">&#167;2</a><br/>The Local Construct - <a href="5-tlc3.html#SP2">&#167;2</a><br/>The Ref Construct - <a href="5-trc.html#SP2">&#167;2</a><br/>The Reference Construct - <a href="5-trc2.html#SP2">&#167;2</a><br/>The Splat Construct - <a href="5-tsc.html#SP2">&#167;2</a><br/>The Val Construct - <a href="5-tvc.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">inter_bookmark</span><span class="plain-syntax"> *</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no node to insert"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">IBM</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"nowhere to insert"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="2-np.html#SP1" class="function-link"><span class="function-syntax">NodePlacement::move_to</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-np.html#SP3" class="function-link"><span class="function-syntax">NodePlacement::to_position</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><a href="2-bkm.html#SP2" class="function-link"><span class="function-syntax">InterBookmark::snapshot</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">)));</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement_wrt_R</span><span class="plain-syntax"> != </span><span class="constant-syntax">BEFORE_NODEPLACEMENT</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">placement_wrt_R</span><span class="plain-syntax"> = </span><span class="constant-syntax">AFTER_NODEPLACEMENT</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">inter_bookmark</span><span class="plain-syntax"> </span><span class="function-syntax">NodePlacement::to_position</span><span class="plain-syntax">(</span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">inter_bookmark</span><span class="plain-syntax"> </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::parent</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">) == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-bkm.html#SP4" class="function-link"><span class="function-syntax">InterBookmark::at_end_of_root</span></a><span class="plain-syntax">(</span><a href="2-bkm.html#SP7" class="function-link"><span class="function-syntax">InterBookmark::tree</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">));</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">placement_wrt_R</span><span class="plain-syntax"> == </span><span class="constant-syntax">AFTER_NODEPLACEMENT</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">placement_wrt_R</span><span class="plain-syntax"> == </span><span class="constant-syntax">IMMEDIATELY_AFTER_NODEPLACEMENT</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="2-np.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Nodes placed after may need to bubble up or down</span><span class="named-paragraph-number">3.1</span></a></span>

<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>&#167;3.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Nodes placed after may need to bubble up or down</span><span class="named-paragraph-number">3.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">R</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="constant-syntax">inter_ti</span><span class="plain-syntax"> </span><span class="identifier-syntax">C_level</span><span class="plain-syntax"> = (</span><span class="constant-syntax">inter_ti</span><span class="plain-syntax">) </span><a href="2-in.html#SP13" class="function-link"><span class="function-syntax">Inode::get_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="constant-syntax">inter_ti</span><span class="plain-syntax"> </span><span class="identifier-syntax">R_level</span><span class="plain-syntax"> = (</span><span class="constant-syntax">inter_ti</span><span class="plain-syntax">) </span><a href="2-in.html#SP13" class="function-link"><span class="function-syntax">Inode::get_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_level</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">R_level</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">R</span><span class="plain-syntax"> = </span><a href="2-it.html#SP4" class="function-link"><span class="function-syntax">InterTree::parent</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">R_level</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">R</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bubbled up out of tree"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_level</span><span class="plain-syntax"> == </span><span class="identifier-syntax">R_level</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-bkm.html#SP4" class="function-link"><span class="function-syntax">InterBookmark::after_this_node</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">C_level</span><span class="plain-syntax"> == </span><span class="identifier-syntax">R_level</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">IBM</span><span class="plain-syntax">.</span><span class="element-syntax">placement_wrt_R</span><span class="plain-syntax"> == </span><span class="constant-syntax">IMMEDIATELY_AFTER_NODEPLACEMENT</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-bkm.html#SP4" class="function-link"><span class="function-syntax">InterBookmark::first_child_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="2-bkm.html#SP4" class="function-link"><span class="function-syntax">InterBookmark::last_child_of</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="string-syntax">"C level: %d, R level: %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">C_level</span><span class="plain-syntax">, </span><span class="identifier-syntax">R_level</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="3-ie.html#SP6" class="function-link"><span class="function-syntax">InterErrors::backtrace</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">STDERR</span><span class="plain-syntax">, </span><span class="identifier-syntax">R</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"bubbled down off of tree"</span><span class="plain-syntax">); </span><span class="comment-syntax"> see above for why</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="2-np.html#SP3">&#167;3</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. Level correction.</b>When material is moved around in code optimisation, the level markers on the
nodes (which cache the tree depth) can become incorrect. So:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">NodePlacement::set_levels</span><span class="plain-syntax">(</span><span class="reserved-syntax">inter_tree_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><a href="2-in.html#SP13" class="function-link"><span class="function-syntax">Inode::set_level</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">P</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_THROUGH_INTER_CHILDREN</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">P</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><a href="2-np.html#SP4" class="function-link"><span class="function-syntax">NodePlacement::set_levels</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="2-bkm.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-bm.html">1</a></li><li class="progresscurrentchapter">2</li><li class="progresssection"><a href="2-it.html">it</a></li><li class="progresssection"><a href="2-in.html">in</a></li><li class="progresssection"><a href="2-bkm.html">bkm</a></li><li class="progresscurrent">np</li><li class="progresssection"><a href="2-tw.html">tw</a></li><li class="progresssection"><a href="2-pck.html">pck</a></li><li class="progresssection"><a href="2-inl.html">inl</a></li><li class="progresssection"><a href="2-st.html">st</a></li><li class="progresssection"><a href="2-sym.html">sym</a></li><li class="progresssection"><a href="2-ann.html">ann</a></li><li class="progresssection"><a href="2-tw2.html">tw2</a></li><li class="progresssection"><a href="2-trn.html">trn</a></li><li class="progresschapter"><a href="3-ic.html">3</a></li><li class="progresschapter"><a href="4-tcc.html">4</a></li><li class="progresschapter"><a href="5-tac.html">5</a></li><li class="progresschapter"><a href="6-tpc.html">6</a></li><li class="progressnext"><a href="2-tw.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

